package com.cowmooed.service.impl;

import com.cowmooed.config.QiNiuYunConfig;
import com.cowmooed.dto.FileUrlItem;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class UploadService {
    private QiNiuYunConfig qiNiuYunConfig;
    private UploadManager uploadManager;
    private String token;
    private Auth auth;
    private ExecutorService executorService;

    public UploadService(QiNiuYunConfig qiNiuYunConfig) {
        this.qiNiuYunConfig = qiNiuYunConfig;
        init();
    }

    private void init() {
        // 初始化七牛云配置
        uploadManager = new UploadManager(new Configuration(Zone.zone2()));
        auth = Auth.create(qiNiuYunConfig.getAccesskey(), qiNiuYunConfig.getSecretkey());
        token = auth.uploadToken(qiNiuYunConfig.getBucketName());

        // 创建线程池用于并发处理文件上传
        executorService = Executors.newFixedThreadPool(10);
    }

    public String upload(MultipartFile file) {
        String basicFilePath = null;
        try {
            String s = System.currentTimeMillis() + "";
            String originalFilename = file.getOriginalFilename();
            System.out.println("原始文件名: " + originalFilename);
            basicFilePath = s + "_" + originalFilename;

            Response response = uploadManager.put(file.getInputStream(), basicFilePath, token, null, null);
            if(!response.isOK()) {
                throw new RuntimeException("上传七牛出错: " + response);
            }
            return qiNiuYunConfig.getUrl() + basicFilePath;
        } catch (QiniuException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 批量处理URL文件上传到CDN
     * @param fileItems 文件URL列表
     * @return 处理后的文件列表
     */
    public List<FileUrlItem> batchUploadFromUrls(List<FileUrlItem> fileItems) {
        List<CompletableFuture<FileUrlItem>> futures = new ArrayList<>();
        System.out.println("开始处理文件: "+ fileItems);

        for (FileUrlItem item : fileItems) {
            CompletableFuture<FileUrlItem> future = CompletableFuture.supplyAsync(() -> {
                try {
                    FileUrlItem processedItem = new FileUrlItem();
                    processedItem.setType(item.getType());

                    // 处理主文件URL
                    if (item.getUrl() != null && !item.getUrl().isEmpty()) {
                        String newUrl = downloadAndUpload(item.getUrl(), item.getType());
                        processedItem.setUrl(newUrl);
                    }

                    // 处理预览图URL
                    if (item.getPreviewImageUrl() != null && !item.getPreviewImageUrl().isEmpty()) {
                        String newPreviewUrl = downloadAndUpload(item.getPreviewImageUrl(), "preview_" + item.getType());
                        processedItem.setPreviewImageUrl(newPreviewUrl);
                    }

                    return processedItem;
                } catch (Exception e) {
                    System.err.println("处理文件失败: " + e.getMessage());
                    // 返回原始数据作为降级方案
                    return item;
                }
            }, executorService);

            futures.add(future);
        }

        // 等待所有任务完成
        List<FileUrlItem> result = new ArrayList<>();
        for (CompletableFuture<FileUrlItem> future : futures) {
            try {
                result.add(future.get());
            } catch (Exception e) {
                System.err.println("获取处理结果失败: " + e.getMessage());
            }
        }

        return result;
    }

    /**
     * 从URL下载文件并上传到CDN
     * @param fileUrl 文件URL
     * @param fileType 文件类型，用于生成文件名
     * @return 新的CDN地址
     */
    private String downloadAndUpload(String fileUrl, String fileType) throws IOException {
        InputStream inputStream = null;
        try {
            // 下载文件
            URL url = new URL(fileUrl);
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(10000); // 10秒连接超时
            connection.setReadTimeout(30000);    // 30秒读取超时
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");

            inputStream = connection.getInputStream();

            // 生成新的文件名
            String fileName = generateFileName(fileUrl, fileType);

            // 上传到七牛云
            Response response = uploadManager.put(inputStream, fileName, token, null, null);
            if (!response.isOK()) {
                throw new RuntimeException("上传七牛失败: " + response);
            }

            return qiNiuYunConfig.getUrl() + fileName;

        } catch (QiniuException e) {
            throw new RuntimeException("七牛上传异常: " + e.getMessage(), e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    System.err.println("关闭输入流失败: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 生成新的文件名
     * @param originalUrl 原始URL
     * @param fileType 文件类型
     * @return 新文件名
     */
    private String generateFileName(String originalUrl, String fileType) {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String extension = getFileExtension(originalUrl);
        return timestamp + "_" + fileType.toLowerCase() + extension;
    }

    /**
     * 从URL中提取文件扩展名
     * @param url 文件URL
     * @return 文件扩展名
     */
    private String getFileExtension(String url) {
        try {
            // 移除URL参数
            String cleanUrl = url.split("\\?")[0];
            int lastDotIndex = cleanUrl.lastIndexOf('.');
            if (lastDotIndex > 0 && lastDotIndex < cleanUrl.length() - 1) {
                return cleanUrl.substring(lastDotIndex);
            }
        } catch (Exception e) {
            System.err.println("提取文件扩展名失败: " + e.getMessage());
        }
        return ""; // 如果无法确定扩展名，返回空字符串
    }
}